package com.itheima.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itheima.client.AddressClient;
import com.itheima.config.PatternProperties;
import com.itheima.domain.po.User;
import com.itheima.domain.vo.UserVO;
import com.itheima.mq.RabbitMqHelper;
import com.itheima.po.Address;
import com.itheima.service.impl.UserServiceImpl;
import com.itheima.utils.SearchHttpAK;

import lombok.RequiredArgsConstructor;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author 虎哥
 * @since 2023-10-28
 */

@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    private final UserServiceImpl userService;
    private final AddressClient addressClient;
    private final RabbitMqHelper rabbitMqHelper;
    private final RabbitTemplate rabbitTemplate;
    private final PatternProperties patternProperties; //从nacos中读取pattern.dateformat
    //private final RestTemplate restTemplate;
    private final HttpClient httpClient;
    private final RestTemplate restTemplate;
    private final RedissonClient redissonClient;
    private final RedisTemplate redisTemplate;

    @Value("${dizhi.zhi}")
    private String aaa;
    @Value("${sky.shop.address}")
    private String address;
    @Value("${sky.baidu.ak}")
    private String ak;


    @GetMapping("/{id}")
    public UserVO getById(@PathVariable Long id) throws Exception {
        UserVO userVO = new UserVO();
        User user = userService.getById(id);

        //1、feign远程调用Address
        List<Address> byUserId = addressClient.getByUserId(id);
        BeanUtils.copyProperties(user, userVO);
        userVO.setList(byUserId);

        //2、MQ延迟通知Address
        System.out.println("MQ延迟");
        String exchange = "trade.delay.topic";
        String key = "tianji";
        Integer integer = 1;
       /* Message message = MessageBuilder
                .withBody("2333".getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .setHeader("x-delay", 10000)
                .build();

        // 2.准备CorrelationData
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());*/
        //rabbitTemplate.convertAndSend(exchange, key, message,correlationData);
        rabbitMqHelper.sendAsync(exchange, key, integer, 10000L);

        //3、nacos热更新
        System.out.println("nacos的热更新：" + patternProperties.getDateformat());
        //4、线程

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 2; i++) {
                    System.out.println("线程" + Thread.currentThread().getName() + "正在工作：" + ":" + i);
                }
            }
        }).start();

        //5、线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5,
                5,
                10,
                TimeUnit.MINUTES,
                new ArrayBlockingQueue<>(3)
        );
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 2; i++) {
                    System.out.println("多线程：第" + Thread.currentThread().getName() + "个线程" + ":" + i);
                }
            }
        });
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 2; i++) {
                    System.out.println("多线程：第" + Thread.currentThread().getName() + "个线程" + ":" + i);
                }
            }
        });
        threadPoolExecutor.shutdown();

        //6、resultType和resultMap的区别
        User user1 = userService.getByUserId(id);
        System.out.println(user1);

        //7、定时任务xxl-job
        System.out.println("xxljob定时任务启动");
        System.out.println("aaa" + aaa);

        //13、httpClient调百度
        String url = "https://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=jCPGyIn4qQwpd5KdOzorYO3O0AjHHIcg&callback=showLocation";
        HttpGet httpGet = new HttpGet(url);
        HttpResponse execute = httpClient.execute(httpGet);

        //restTemplate调百度
        String forObject = restTemplate.getForObject(url, String.class);
        String replace = forObject.replace("showLocation&&showLocation(", "").replace(")", "");

        JSONObject object = JSON.parseObject(replace);
        //JSONObject status = object.getJSONObject("status");

        // JSONObject jsonObject = JSONObject.parseObject(forObject);
        JSONObject result = object.getJSONObject("result");
        System.out.println("结果：" + result.toString());
        HttpEntity entity = execute.getEntity();

        //14、百度自带的工具类
        //SearchHttpAK.text();

        //15、老吕的文字转语音工具类
        //TextToSpeechUtils.textToSpeech(id.toString());

        //16、生成报表
        //List<Address> list = userVO.getList();

        //17、Redis连接
        redisTemplate.opsForValue().set("key", 1);
        System.out.println(redisTemplate.opsForValue().get("key"));

        //18、分布式锁
        RLock anyLock = redissonClient.getLock("anyLock");
        try {
            boolean b = anyLock.tryLock(1, 10, TimeUnit.SECONDS);
            if (!b) {
                System.out.println("加锁失败、执行相关代码逻辑");
            } else {
                System.out.println("加锁成功、执行相关代码逻辑");
            }
        } finally {
            //释放锁
            anyLock.unlock();
        }

        //19、对各种集合进行排序
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(30);
        arrayList.add(60);
        arrayList.add(20);
        arrayList.sort((o1, o2) -> o1-o2);
        System.out.println("集合排序方式一："+arrayList);
        CollectionUtil.sort(arrayList, (o1, o2) -> o2-o1);
        System.out.println("集合排序方式二："+arrayList);
        return userVO;

        //20、拦截器



    }

}
